namespace Plugins.Library
{
    using System.Diagnostics.CodeAnalysis;
    using System.Threading;

    public abstract class PluginWorkItemContainer<T>
    {
        [SuppressMessage("Microsoft.Design", "CA1000")]
        [SuppressMessage("Microsoft.Usage", "CA2211")]
        [SuppressMessage("Microsoft.Security", "CA2104")]
        public static PluginWorkItemContainer<T> Current;

        private T _item;

        public abstract void Signal();

        public abstract void Wait();

        protected PluginWorkItemContainer(T item)
        {
            this._item = item;
        }

        public T Item
        {
            get
            {
                return this._item;
            }
        }

        protected abstract void BeginProcess();
        
        protected abstract void Process();
        
        protected abstract void EndProcess();

        [SuppressMessage("Microsoft.Design", "CA1000")]
        public static void QueryAsync(PluginWorkItemContainer<T> item)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(item.Run), item);
        }

        [SuppressMessage("Microsoft.Design", "CA1000")]
        public static void QuerySync(PluginWorkItemContainer<T> item)
        {
            item.Run(item);
        }

        protected virtual void Run(object value)
        {
            PluginWorkItemContainer<T> item = value as PluginWorkItemContainer<T>;
            if (item != null)
            {
                item.BeginProcess();
                item.Process();
                item.EndProcess();
            }
        }

        public PluginWorkItemContainer<T> Link
        {
            get;
            set;
        }

        public void SetWorkItem(T value)
        {
            this._item = value;
        }
    }
}

